﻿namespace ufida.u9.ait.openapi
{
    using Newtonsoft.Json.Linq;
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Data;
    using System.Linq;
    using System.Text;
    using System.Web.UI.WebControls;
    using ufida.u9.ait.openapi.utils;
    using UFSoft.UBF.AopFrame;	
	using UFSoft.UBF.Util.Context;
    using UFSoft.UBF.Util.DataAccess;

    /// <summary>
    /// CommonQuerySV partial 
    /// </summary>	
    public partial class CommonQuerySV 
	{	
		internal BaseStrategy Select()
		{
			return new CommonQuerySVImpementStrategy();	
		}		
	}
	
	#region  implement strategy	
	/// <summary>
	/// Impement Implement
	/// 
	/// </summary>	
	internal partial class CommonQuerySVImpementStrategy : BaseStrategy
	{
		public CommonQuerySVImpementStrategy() { }

		public override object Do(object obj)
		{						
			CommonQuerySV bpObj = (CommonQuerySV)obj;

            try
            {
                if (bpObj.Data == null)
                    throw new Exception("传入数据为空");
                if (string.IsNullOrEmpty(bpObj.Data.ViewName))
                    throw new Exception("传入参数[ViewName]为空");

                //读取配置文件,并校验
                JObject config = JSONUtils.readJSONFile(U9Utils.GetU9Dir() + "/configs/aitconfig.json");
                //校验表名
                ValidTable(bpObj.Data.ViewName, config);
                //校验viewpath
                ValidPath(bpObj.Data.ViewPath);
                //获取数据
                List<Dictionary<string, object>> retlist = U9Utils.RunSQL(
                    bpObj.Data.ViewName, bpObj.Data.ViewPath, bpObj.Data.ViewOrder);
                //聚合数据
                retlist=AggDatas(retlist, bpObj.Data.ViewName, config);
                //尾部处理
                String wbPath = $"CommonQuerySV.tableConfig.{bpObj.Data.ViewName}.wb";
                JToken wbToken = JSONUtils.getJToken(config, wbPath);
                JToken ret= RemoveKeySuffixes(JSONUtils.toJArray(retlist)
                    , JSONUtils.toListString(wbToken));
                return ResultUtils.success(bpObj, bpObj.Data, ret);
            }
            catch (Exception ex)
            {
				return ResultUtils.error(bpObj, bpObj.Data, ex);
			}
		}

        /// <summary>
        /// 创建一个新的 JToken，移除所有属性名结尾的指定后缀（如 _wb1, _wb2），不修改原始 token。
        /// </summary>
        /// <param name="originalToken">原始 JToken</param>
        /// <param name="suffixes">要移除的后缀列表，如 new List<string> { "_wb1", "_wb2" }</param>
        /// <returns>清理后的新 JToken；若输入为 null 则返回 null</returns>
        public static JToken RemoveKeySuffixes(JToken originalToken, List<string> suffixes)
        {
            if (originalToken == null || suffixes == null || suffixes.Count == 0)
                return originalToken?.DeepClone(); // 返回深拷贝以确保不共享引用

            switch (originalToken)
            {
                case JArray array:
                    var newArray = new JArray();
                    foreach (var item in array)
                    {
                        newArray.Add(RemoveKeySuffixes(item, suffixes));
                    }
                    return newArray;

                case JObject obj:
                    var newObject = new JObject();
                    foreach (var prop in obj.Properties())
                    {
                        string originalName = prop.Name;
                        string newName = originalName;

                        // 尝试移除匹配的后缀
                        foreach (string suffix in suffixes)
                        {
                            if (originalName.EndsWith(suffix, StringComparison.Ordinal))
                            {
                                newName = originalName.Substring(0, originalName.Length - suffix.Length);
                                break; // 只移除第一个匹配的后缀
                            }
                        }

                        // 递归处理值
                        JToken newValue = RemoveKeySuffixes(prop.Value, suffixes);

                        // 添加到新对象（如果 newName 已存在，后面的会覆盖前面的）
                        newObject[newName] = newValue;
                    }
                    return newObject;

                default:
                    // 值类型（string, number, bool, null 等）直接深拷贝返回
                    return originalToken.DeepClone();
            }
        }

        /// <summary>
        /// 聚合数据,将数据聚合为主子结构或主子孙结构
        /// 支持多级聚合
        /// </summary>
        /// <param name="dataList">数据集合</param>
        /// <param name="tableName">视图名称</param>
        /// <param name="config">配置信息</param>
        /// <returns>聚合后的数据</returns>
        private List<Dictionary<string, object>> AggDatas(List<Dictionary<string, object>> dataList
            , string tableName,JObject config)
        {
            if (dataList == null || !dataList.Any())
                return dataList;

            // 读取配置
            if (!(config["CommonQuerySV"]?["tableConfig"] is JObject tableConfig) ||
                !(tableConfig[tableName] is JObject aggConfig) ||
                !(aggConfig["fengge"] is JArray fenggeArray) ||
                fenggeArray.Count == 0)
            {
                return dataList;
            }

            // 解析所有 fengge 规则
            var rules = new List<(string field, string attr, string headkey)>();
            foreach (JObject ruleObj in fenggeArray)
            {
                rules.Add((
                    field: ruleObj.Value<string>("field"),
                    attr: ruleObj.Value<string>("attr"),
                    headkey: ruleObj.Value<string>("headkey")
                ));
            }

            // 获取原始字段顺序（假设所有行字段顺序一致）
            var allKeys = dataList[0].Keys.ToList();

            // 递归构建嵌套结构
            return BuildNestedStructure(dataList, rules, allKeys, level: 0);
        }

        /// <summary>
        /// 递归构建嵌套结构
        /// </summary>
        /// <param name="currentData">当前层级的数据</param>
        /// <param name="rules">所有分隔规则</param>
        /// <param name="availableFields">当前可用的字段范围（从上一级 field 之后开始）</param>
        /// <param name="level">当前处理的规则层级（0=主表，1=子表，2=孙表...）</param>
        private List<Dictionary<string, object>> BuildNestedStructure(
            List<Dictionary<string, object>> currentData,
            List<(string field, string attr, string headkey)> rules,
            List<string> availableFields,
            int level)
        {
            if (currentData == null || !currentData.Any() || level >= rules.Count)
            {
                // 没有更多规则，返回原始数据（最后一级明细）
                return currentData.Select(row =>
                {
                    var dict = new Dictionary<string, object>();
                    foreach (var key in availableFields)
                    {
                        dict[key] = row.ContainsKey(key) ? row[key] : null;
                    }
                    return dict;
                }).ToList();
            }

            var (field, attr, headkey) = rules[level];

            // 查找 field 在 availableFields 中的位置
            int fieldIndex = availableFields.IndexOf(field);
            if (fieldIndex == -1)
            {
                // 如果分隔字段不存在，直接返回当前数据（不再分层）
                return currentData.Select(row =>
                {
                    var dict = new Dictionary<string, object>();
                    foreach (var key in availableFields)
                        dict[key] = row.ContainsKey(key) ? row[key] : null;
                    return dict;
                }).ToList();
            }

            // 主表字段：field 之前的部分
            var masterFields = availableFields.Take(fieldIndex).ToList();
            // 下一级可用字段：field 之后的部分
            var nextLevelFields = availableFields.Skip(fieldIndex + 1).ToList();

            // 按 headkey 分组
            if (currentData[0][headkey] == null) 
                throw new Exception($"headkey字段[{headkey}]不存在");
            var grouped = currentData.GroupBy(row => row[headkey]?.ToString() ?? string.Empty);

            var result = new List<Dictionary<string, object>>();

            foreach (var group in grouped)
            {
                var firstRow = group.First();

                // 构建当前层级主记录（只含 masterFields）
                var master = new Dictionary<string, object>();
                foreach (var key in masterFields)
                {
                    master[key] = firstRow.ContainsKey(key) ? firstRow[key] : null;
                }

                // 递归构建下一级数据
                var nextLevelData = BuildNestedStructure(group.ToList(), rules, nextLevelFields, level + 1);

                // 将下一级结果挂到当前主记录的 attr 字段
                master[attr] = nextLevelData;

                result.Add(master);
            }

            return result;
        }

        /// <summary>
        /// 校验tableName在配置文件中存在
        /// </summary>
        /// <param name="tableName">传入表名</param>
        /// <param name="config">配置文件</param>
        private static void ValidTable(string tableName, JObject config)
        {
            JArray tables = (JArray)config["CommonQuerySV"]["tables"];
            foreach (var table in tables)
            {
                if (((JValue)table).Value.Equals(tableName))
                    return;
            }
            throw new Exception($"配置中不包含视图[{tableName}]");
        }

        private static void ValidPath(string path)
        {
            if (string.IsNullOrEmpty(path)) return;

            if (path.IndexOf("update ", StringComparison.OrdinalIgnoreCase) >= 0
                || path.IndexOf("delete ", StringComparison.OrdinalIgnoreCase) >= 0
                || path.IndexOf("select ", StringComparison.OrdinalIgnoreCase) >= 0
                || path.IndexOf(" union ", StringComparison.OrdinalIgnoreCase) >= 0
                || path.IndexOf(" from ", StringComparison.OrdinalIgnoreCase) >= 0
                || path.IndexOf(" join ", StringComparison.OrdinalIgnoreCase) >= 0
                || path.IndexOf(" exists ", StringComparison.OrdinalIgnoreCase) >= 0
                )
            {
                throw new Exception("查询SQL不符合规范");
            }
        }
    }

	#endregion
	
	
}